package docmodel;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public abstract class Field {

	/**
	 * 
	 * @param marker
	 * @return
	 */
	public static Field getFieldByMarker(String marker){
		if(isLabel(marker)) return new FloatingField(marker);
		else if(isCostant(marker)) return new FloatingFieldCostant(marker);
		else return null;
	}
	
	/** */
	private static String patternLabel = "<#\\w*\\(.*,L\\)#>"; 

	/** */
	private static Pattern pLabel = Pattern.compile(patternLabel); 
	
	public static boolean isLabel(String marker) {
		Matcher matcher = pLabel.matcher(marker);
		return matcher.matches();
	}
	/** */
	private static String patternCostant = "<#\\w*\\(.*,K\\)#>";

	/** */
	private static Pattern pCostant = Pattern.compile(patternCostant);

	/**
	 * 
	 * @param marker
	 * @return
	 */
	public static boolean isCostant(String marker) {
		Matcher matcher = pCostant.matcher(marker);
		return matcher.matches();
	}
	
	/** Regular Expression */
	static String patternString = "<#\\w*\\(.*\\)#>";

	/** Crea un pattern a partire dalla Regular Expression*/
	static Pattern p = Pattern.compile(Field.patternString);

	/** */
	protected String name, id;

	/** */
	protected String code;

	public String getCode() {
		return code;
	}

	/** */
	protected String stroke, typeface, topInset, rightInset, leftInset,
			bottomInset, vAlign, match, ref;

	/** */
	protected Element span, field;


	/**
	 * 
	 * @param fullMarkerCode
	 */
	public Field(String fullMarkerCode)
	{
		// DEFAULT Values
		stroke      = "lowered";
		typeface    = "Myriad Pro";
		topInset    = "1mm";
		rightInset  = "1mm";
		leftInset   = "1mm";
		bottomInset = "1mm";
		vAlign	    = "middle";
		match 	    = "dataRef";
		
		code = fullMarkerCode.substring(fullMarkerCode.indexOf("(") + 1,
				fullMarkerCode.indexOf(","));
		name = fullMarkerCode.substring(2, fullMarkerCode.indexOf("("));
	}

	/**
	 * 
	 * @return
	 */
	public String getName() {
		return this.name;
	}

	/**
	 * 
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 
	 * @return
	 */
	public String getId() {
		return id;
	}

	/**
	 * 
	 * @param id
	 */
	public void setId(String id) {
		this.id = id;
	}
	
	/**
	 * 
	 * @param doc
	 * @return
	 */
	public Element getFieldElement(Document doc) {
		createFieldElement(doc);
		return this.field;
	}

	/**
	 * @param doc
	 */
	private void createFieldElement(Document doc) {

		Element ui, textEdit, border, edge, font, margin, para, bind, caption, value, text;
		Element field = null;
		field = doc.createElement("field");

		// hidden
		field.setAttribute("presence", "hidden");

		/** --- crea il 1 figlio di FIELD: "ui" */
		ui = doc.createElement("ui");

		// crea il figlio di UI: "textEdit"
		textEdit = doc.createElement("textEdit");
		ui.appendChild(textEdit);

		// crea il figlio di "textEdit": "border"
		border = doc.createElement("border");
		textEdit.appendChild(border);

		// crea il figlio di "border": "edge"
		edge = doc.createElement("edge");
		border.appendChild(edge);

		// attributi "edge"
		edge.setAttribute("stroke", this.stroke);

		// --- crea il 2 figlio di FIELD: "font"
		font = doc.createElement("font");
		// attributi "font"
		font.setAttribute("typeface", this.typeface);

		// --- crea il 3 figlio di FIELD: "margin"
		margin = doc.createElement("margin");

		// attributi "margin"
		margin.setAttribute("topInset", this.topInset);
		margin.setAttribute("rightInset", this.rightInset);
		margin.setAttribute("leftInset", this.leftInset);
		margin.setAttribute("bottomInset", this.bottomInset);

		// --- crea il 4 figlio di FIELD
		para = doc.createElement("para");
		// attributi "para"
		para.setAttribute("vAlign", this.vAlign);

		// --- crea il 5 figlio di FIELD
		bind = doc.createElement("bind");
		// attributi "bind"
		bind.setAttribute("match", this.match);
		bind.setAttribute("ref", this.ref);

		// --- crea il 6 figlio di FIELD
		caption = doc.createElement("caption");

		// crea il figlio di "caption"
		value = doc.createElement("value");
		caption.appendChild(value);

		// crea il figlio di "value"
		text = doc.createElement("text");
		value.appendChild(text);

		// --- attributi FIELD ---
		field.setAttribute("name", this.name);
		field.setAttribute("id", this.id);
		/*
		 * presence = "hidden" access = "readOnly"
		 * 
		 * h="9mm" w="62mm" x="0mm" y="0mm"
		 */

		// --- aggiunge i figli di FIELD ---
		field.appendChild(ui);
		field.appendChild(font);
		field.appendChild(margin);
		field.appendChild(para);
		field.appendChild(bind);
		field.appendChild(caption);

		//
		this.field = field;
	}

	/**
	 * 
	 * @param doc
	 * @return
	 */
	public Element getSpanElement(Document doc) {
		createSpanElement(doc);
		return this.span;
	}

	/**
	 * @param doc
	 */
	private void createSpanElement(Document doc) {
		Element span;
		span = doc.createElement("span");
		span.setAttribute("xfa:embedType", "uri");
		span.setAttribute("xfa:embedMode", "raw");
		span.setAttribute("xfa:embed", "#" + this.id);

		this.span = span;
	}
	
	/**
	 * usato dalla GUI
	 * 
	 * @return
	 */
	public String[] toArrayString() {
		String[] str = { name, "" + code };
		return str;
	}
}
